package ua.khpi.si.kit49.diploma.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.stereotype.Component;

import ua.khpi.si.kit49.diploma.core.Constants;
import ua.khpi.si.kit49.diploma.core.JsonRegistrationMessage;
import ua.khpi.si.kit49.diploma.db.dto.User;
import ua.khpi.si.kit49.diploma.service.RegistrationService;

/**
 * Class is in charge of the verification of the data related to registration or
 * update users
 * 
 * @author netstalk3r
 * 
 */

@Component("registrationValidator")
public class RegistrationValidator {

	private static final Logger log = Logger
			.getLogger(RegistrationValidator.class);

	@Autowired(required = true)
	RegistrationService registrationService;

	@Autowired(required = true)
	private ReloadableResourceBundleMessageSource messageSource;

	private static final String emailPattern = "^([a-z0-9_-]+\\.)*[a-z0-9_-]+@[a-z0-9_-]+(\\.[a-z0-9_-]+)*\\.[a-z]{2,6}$";
	private static final String rolePattern = "ROLE_(USER|ADMIN)";
	private static final Integer MIN_LOGIN_LENGHT = 3;
	private static final Integer MIN_PASSWORD_LENGHT = 6;

	public void validate(User user, String confirmPass,
			JsonRegistrationMessage jsonRegistrationMessage, Locale loc,
			Boolean isAdd) {
		String error = null;
		List<String> errors = new ArrayList<String>();

		String userName = user.getUsername();
		if (userName.equals(null) || userName.length() == 0) {
			error = messageSource.getMessage(
					"company.registration.valid.required.username", null,
					Constants.DEFAULT_MESSAGE, loc);
			error = StringEscapeUtils.unescapeJava(error);
			log.debug(error);
			jsonRegistrationMessage.setLoginError(error);
		} else {
			if (userName.length() < MIN_LOGIN_LENGHT) {
				error = messageSource.getMessage(
						"company.registration.valid.login.short", null,
						Constants.DEFAULT_MESSAGE, loc);
				error = StringEscapeUtils.unescapeJava(error);
				log.debug(error);
				jsonRegistrationMessage.setLoginError(error);
			}
		}

		String email = user.getEmail();
		if (email.equals(null) || email.length() == 0) {
			error = messageSource.getMessage(
					"company.registration.valid.required.email", null,
					Constants.DEFAULT_MESSAGE, loc);
			error = StringEscapeUtils.unescapeJava(error);
			log.debug(error);
			jsonRegistrationMessage.setEmailError(error);
		} else {
			Pattern pattern = Pattern.compile(emailPattern);
			Matcher matcher = pattern.matcher(user.getEmail());
			if (!matcher.matches()) {
				error = messageSource.getMessage(
						"company.registration.valid.wrong.email", null,
						Constants.DEFAULT_MESSAGE, loc);
				error = StringEscapeUtils.unescapeJava(error);
				log.debug(error);
				jsonRegistrationMessage.setEmailError(error);
			}
		}

		String password = user.getPassword();
		if (password.equals(null) || password.length() == 0) {
			error = messageSource.getMessage(
					"company.registration.valid.required.password", null,
					Constants.DEFAULT_MESSAGE, loc);
			error = StringEscapeUtils.unescapeJava(error);
			log.debug(error);
			jsonRegistrationMessage.setPasswordError(error);
		} else {
			if (password.length() < MIN_PASSWORD_LENGHT) {
				error = messageSource.getMessage(
						"company.registration.valid.password.short", null,
						Constants.DEFAULT_MESSAGE, loc);
				error = StringEscapeUtils.unescapeJava(error);
				log.debug(error);
				jsonRegistrationMessage.setPasswordError(error);
			}
		}

		if (!user.getPassword().equals(confirmPass)) {
			String passError = messageSource.getMessage(
					"company.registration.valid.passwords.do.not.match", null,
					Constants.DEFAULT_MESSAGE, loc);
			passError = StringEscapeUtils.unescapeJava(passError);
			log.debug(passError);
			errors.add(passError);
		}

		if (isAdd) {

			User checkUser = registrationService.getUserByUsername(user
					.getUsername());
			if (checkUser != null) {
				error = messageSource.getMessage(
						"company.registration.valid.exist.username", null,
						Constants.DEFAULT_MESSAGE, loc);
				error = StringEscapeUtils.unescapeJava(error);
				log.debug(error);
				errors.add(error);
			}

			checkUser = registrationService.getUserByEmail(user.getEmail());
			if (checkUser != null) {
				error = messageSource.getMessage(
						"company.registration.valid.exist.email", null,
						Constants.DEFAULT_MESSAGE, loc);
				error = StringEscapeUtils.unescapeJava(error);
				log.debug(error);
				errors.add(error);
			}
		}

		if (errors.size() != 0) {
			jsonRegistrationMessage.setErrors(errors);
		}

		if ((errors.size() > 0)
				|| jsonRegistrationMessage.getEmailError() != null
				|| jsonRegistrationMessage.getLoginError() != null
				|| jsonRegistrationMessage.getPasswordError() != null) {
			jsonRegistrationMessage.setValid(false);
		} else {
			jsonRegistrationMessage.setValid(true);
		}

	}

	public void validateRole(JsonRegistrationMessage jsonRegistrationMessage,
			String role, Locale loc) {
		Pattern pattern = Pattern.compile(rolePattern);
		Matcher matcher = pattern.matcher(role);
		if (!matcher.matches()) {
			jsonRegistrationMessage.setValid(false);
			String error = messageSource.getMessage(
					"company.roles.role.incorrect", null,
					Constants.DEFAULT_MESSAGE, loc);
			error = StringEscapeUtils.unescapeJava(error);
			log.debug(error);
			List<String> errors = new ArrayList<String>();
			errors.add(error);
			jsonRegistrationMessage.setErrors(errors);
		}
	}
}
